package cn.wgx.modules.sys.services;

import cn.wgx.commons.util.ReflectionUtils;
import cn.wgx.commons.util.Validation;
import cn.wgx.modules.base.entity.BaseFavoriteAndLikeEntity;
import cn.wgx.modules.base.services.BaseService;
import cn.wgx.modules.sys.entity.SysUserLike;
import cn.wgx.modules.sys.entity.SysUserLikeExample;
import cn.wgx.modules.sys.entity.mapper.SysUserFavoriteExtendMapper;
import cn.wgx.modules.sys.entity.mapper.SysUserLikeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


@Service
public class SysUserLikeService extends BaseService<SysUserLike> {

    @Resource
    SysUserLikeMapper mapper;

    @Resource
    SysUserFavoriteExtendMapper sysUserFavoriteExtendMapper;


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Transactional(readOnly = true)
    public List<SysUserLike> getList(SysUserLike record, Boolean desc) {
		SysUserLikeExample example = new SysUserLikeExample();
		if(record != null){
            SysUserLikeExample.Criteria criteria = example.createCriteria();
            if(record.getRes_id() != null){
                criteria.andRes_idEqualTo(record.getRes_id());
            }
            if(record.getUser_id() != null){
                criteria.andUser_idEqualTo(record.getUser_id());
            }
            if(record.getType() != null){
                criteria.andTypeEqualTo(record.getType());
            }
        }
		example.setOrderByClause("createDate " + (desc?"desc": "asc"));
		return mapper.selectByExample(example);
    }

    public List getUserByLike(Integer res_id, Integer type) {

        return null;
    }

    @Override
    public List<SysUserLike> getListByIds(List<Integer> ids) {
        if(ids == null || ids.isEmpty()){
            return emptyList;
        }
        SysUserLikeExample example = new SysUserLikeExample();
        example.createCriteria().andLike_idIn(ids);
        return mapper.selectByExample(example);
    }

    @Transactional(readOnly = true)
    public SysUserLike getOne(Integer user_id,Integer type, Integer res_id) {
        SysUserLike record = new SysUserLike();
        record.setUser_id(user_id);
        record.setType(type);
        record.setRes_id(res_id);
        List<SysUserLike> list = getList(record, true);
        if(list != null && !list.isEmpty()){
            return list.get(0);
        }
		return null;
    }

    @Transactional(readOnly = true)
    public Integer getCountByRes_id(Integer res_id, Integer type){
        return sysUserFavoriteExtendMapper.getLikeCountResIdAndType(res_id, type);
    }

    @Transactional(readOnly = true)
    public void wrapLike(List<? extends BaseFavoriteAndLikeEntity> targetList, Integer type, String idName, Integer user_id) {
        wrapHasLike(targetList, type, idName, user_id);
        wrapLikeNum(targetList, type, idName);
    }


    //包装检测是否已点赞
    private void wrapHasLike(List<? extends BaseFavoriteAndLikeEntity> targetList, Integer type, String idName, Integer user_id) {
        if (Validation.isNullOrZero(user_id) || !(type == 1 || type == 2 || type == 3)
                || targetList == null || targetList.isEmpty()) {
            return;
        }
        List<Integer> ids = getIntegerIdList(targetList, idName);
        SysUserLikeExample example = new SysUserLikeExample();
        example.createCriteria().andRes_idIn(ids).andTypeEqualTo(type).andUser_idEqualTo(user_id);
        List<SysUserLike> sysUserFavorites = mapper.selectByExample(example);
        for (int i = 0, n = sysUserFavorites.size(), m = targetList.size(); i < n; i++) {
            for (int j = 0; j < m; j++) {
                BaseFavoriteAndLikeEntity baseFavoriteEntity = targetList.get(j);
                if (sysUserFavorites.get(i).getRes_id().equals(ReflectionUtils.getValueByFieldName(baseFavoriteEntity, idName))) {
                    baseFavoriteEntity.setLike(true);
                }
            }
        }
    }


    //检测每个资源点赞数量
    private void wrapLikeNum(List<? extends BaseFavoriteAndLikeEntity> targetList, Integer type, String idName) {
        if (targetList == null || targetList.isEmpty()) {
            return;
        }
        List<Integer> ids = getIntegerIdList(targetList, idName);
        int n = ids.size();
        String keyPre = getCacheKeyPre(type);
        List<String> idsStr = new ArrayList<>();
        for (Integer id : ids) {
            idsStr.add(keyPre + id);
        }
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        List<String> resList = stringStringValueOperations.multiGet(idsStr);//批量取出结果
        if (resList != null && resList.size() == n) {
            for (int i = 0; i < n; i++) {
                Object o = resList.get(i);
                if (o == null) {
                    Integer integer = ids.get(i);
                    Integer countByRes_id = getCountByRes_id(integer, type);
                    resList.set(i, countByRes_id + "");
                    stringStringValueOperations.set(keyPre + integer, countByRes_id + "");
                }
            }
        }
        for (int i = 0, m = targetList.size(); i < n; i++) {
            for (int j = 0; j < m; j++) {
                BaseFavoriteAndLikeEntity baseFavoriteEntity = targetList.get(j);
                if (ids.get(i).equals(ReflectionUtils.getValueByFieldName(baseFavoriteEntity, idName))) {
                    baseFavoriteEntity.setLikeNum(Integer.parseInt(resList.get(i)));
                }
            }
        }
    }

    //1课程,2作业,3笔记
    public boolean checkHas(Integer type, Integer res_id){       
        return false;
    }

    @Transactional
    public SysUserLike insertOne( SysUserLike record) {
        filter(record, true);
        int i = mapper.insertSelective(record);
        record.set_result(i);
        if(i > 0){
            new Thread(()->{
                ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
                String k = getCacheKeyPre(record.getType()) + record.getRes_id();
                if(stringStringValueOperations.get(k) != null){
                    stringStringValueOperations.increment(k);
                }
            }).start();
        }
        return record;
    }


    @Transactional
    public int deleteOne( Integer user_id, Integer type, Integer res_id) {
        SysUserLikeExample example = new SysUserLikeExample();
        example.createCriteria().andUser_idEqualTo(user_id).andTypeEqualTo(type).andRes_idEqualTo(res_id);
        int i = mapper.deleteByExample(example);
        if(i > 0){
            new Thread(()->{
                ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
                String k = getCacheKeyPre(type) + res_id;
                if(stringStringValueOperations.get(k) != null){
                    stringStringValueOperations.decrement(k);
                }
            }).start();
        }
        return i;
    }

    private String getCacheKeyPre(Integer type){
        return "like_" + type + "_";
    }

}